using System;
using System.Collections.Generic;
using System.Text;

namespace PastCrew.Games.Chess.Engine.Entities.Pieces
{
    public sealed class King : BasePiece
    {

        #region constructors

        /// <summary>
        /// 
        /// </summary>
        public King()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pieceColor"></param>
        public King(Color pieceColor)
        {
            base.Color = pieceColor;
        }

        #endregion

        #region public methods

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public sealed override List<Entities.SquareStatus> GetValidMoves()
        {
            #region knight rule set

            Board.Position currentPosition = this.CurrentSquare.Position;
            List<Entities.SquareStatus> validPositions = new List<Entities.SquareStatus>();
            bool castling = true;

            // King moves down
            if (currentPosition.Y >= 1)
            {
                Board.Square squareDown = Board.GetSquare((currentPosition.X), (currentPosition.Y - 1));
                if (!squareDown.Occupied)
                {
                    Entities.SquareStatus squareStat = new SquareStatus(squareDown, MoveResult.valid);
                    validPositions.Add(squareStat);
                }
                else
                {
                    if (squareDown.Occupant.Color != this.Color)
                    {
                        Entities.SquareStatus squareStat = new SquareStatus(squareDown, MoveResult.valid & MoveResult.strike);
                        validPositions.Add(squareStat);
                    }
                }
            }

            // King moves up
            if (currentPosition.Y <= 6)
            {
                Board.Square squareUp = Board.GetSquare((currentPosition.X), (currentPosition.Y + 1));
                if (!squareUp.Occupied)
                {
                    Entities.SquareStatus squareStat = new SquareStatus(squareUp, MoveResult.valid);
                    validPositions.Add(squareStat);
                }
                else
                {
                    if (squareUp.Occupant.Color != this.Color)
                    {
                        Entities.SquareStatus squareStat = new SquareStatus(squareUp, MoveResult.valid & MoveResult.strike);
                        validPositions.Add(squareStat);
                    }
                }
            }

            // King moves left
            if (currentPosition.X >= 1)
            {
                Board.Square squareLeft = Board.GetSquare((currentPosition.X - 1), currentPosition.Y);
                if (!squareLeft.Occupied)
                {
                    Entities.SquareStatus squareStat = new SquareStatus(squareLeft, MoveResult.valid);
                    validPositions.Add(squareStat);
                }
                else
                {
                    if(squareLeft.Occupant.Color != this.Color)
                    {
                        Entities.SquareStatus squareStat = new SquareStatus(squareLeft, MoveResult.valid & MoveResult.strike);
                        validPositions.Add(squareStat);
                    }
                }
                // Move King down diagonal
                if (currentPosition.Y >= 1)
                {                    
                    Board.Square squareDiagonalLeftDown = Board.GetSquare((currentPosition.X - 1), (currentPosition.Y - 1));
                    if (!squareDiagonalLeftDown.Occupied)
                    {
                        Entities.SquareStatus squareStat = new SquareStatus(squareDiagonalLeftDown, MoveResult.valid);
                        validPositions.Add(squareStat);
                    }
                    else
                    {
                        if (squareDiagonalLeftDown.Occupant.Color != this.Color)
                        {
                            Entities.SquareStatus squareStat = new SquareStatus(squareDiagonalLeftDown, MoveResult.valid & MoveResult.strike);
                            validPositions.Add(squareStat);
                        }
                    }
                }
                // Move King up diagonal
                if (currentPosition.Y <= 6)
                {                    
                    Board.Square squareDiagonalLeftUp = Board.GetSquare((currentPosition.X - 1), (currentPosition.Y + 1));
                    if (!squareDiagonalLeftUp.Occupied)
                    {
                        Entities.SquareStatus squareStat = new SquareStatus(squareDiagonalLeftUp, MoveResult.valid);
                        validPositions.Add(squareStat);
                    }
                    else
                    {
                        if (squareDiagonalLeftUp.Occupant.Color != this.Color)
                        {
                            Entities.SquareStatus squareStat = new SquareStatus(squareDiagonalLeftUp, MoveResult.valid & MoveResult.strike);
                            validPositions.Add(squareStat);
                        }
                    }
                }
            }
            // King moves right
            if (currentPosition.X <= 6)
            {
                Board.Square squareRight = Board.GetSquare((currentPosition.X + 1), currentPosition.Y);
                if (!squareRight.Occupied)
                {
                    Entities.SquareStatus squareStat = new SquareStatus(squareRight, MoveResult.valid);
                    validPositions.Add(squareStat);
                }
                else
                {
                    if(squareRight.Occupant.Color != this.Color)
                    {
                        Entities.SquareStatus squareStat = new SquareStatus(squareRight, MoveResult.valid & MoveResult.strike);
                        validPositions.Add(squareStat);
                    }
                }
                // Move King down diagonal
                if (currentPosition.Y >= 1)
                {
                    Board.Square squareDiagonalRightDown = Board.GetSquare((currentPosition.X + 1), (currentPosition.Y - 1));
                    if (!squareDiagonalRightDown.Occupied)
                    {
                        Entities.SquareStatus squareStat = new SquareStatus(squareDiagonalRightDown, MoveResult.valid);
                        validPositions.Add(squareStat);
                    }
                    else
                    {
                        if (squareDiagonalRightDown.Occupant.Color != this.Color)
                        {
                            Entities.SquareStatus squareStat = new SquareStatus(squareDiagonalRightDown, MoveResult.valid & MoveResult.strike);
                            validPositions.Add(squareStat);
                        }
                    }
                }
                // Move King up diagonal
                if (currentPosition.Y <= 6)
                {
                    Board.Square squareDiagonalRightUp = Board.GetSquare((currentPosition.X + 1), (currentPosition.Y + 1));
                    if (!squareDiagonalRightUp.Occupied)
                    {
                        Entities.SquareStatus squareStat = new SquareStatus(squareDiagonalRightUp, MoveResult.valid);
                        validPositions.Add(squareStat);
                    }
                    else
                    {
                        if(squareDiagonalRightUp.Occupant.Color != this.Color)
                        {
                            Entities.SquareStatus squareStat = new SquareStatus(squareDiagonalRightUp, MoveResult.valid & MoveResult.strike);
                            validPositions.Add(squareStat);
                        }
                    }
                }
            }

            int rook1X, rook2X;
            int rook1Y, rook2Y;
            if (this.Color == Color.white)
            {
                rook1X = 0;
                rook1Y = 0;
                rook2X = 7;
                rook2Y = 0;
            }
            else
            {
                rook1X = 0;
                rook1Y = 7;
                rook2X = 7;
                rook2Y = 7;
            }

            // Castling left
            castling = true;
            if (!this.HasMoved && !(Board.GetSquare(rook1X, rook1Y).Occupant.HasMoved))
            {
                for (int x = (currentPosition.X - 1); x >= 1; x--)
                {
                    Board.Square square = Board.GetSquare(x, rook1Y);
                    if (square.Occupied || square.GetThreatenedByList(this.Color).Count != 0)
                    {
                        castling = false;
                        break;
                    }                    
                }
            }
            if (castling)
            {
                Entities.SquareStatus squareStat = new SquareStatus(Board.GetSquare(rook1X, rook1Y), MoveResult.valid & MoveResult.castling);
                validPositions.Add(squareStat);
            }

            // Castling right
            castling = true;
            if (!this.HasMoved && !(Board.GetSquare(rook2X, rook2Y).Occupant.HasMoved))
            {
                for (int x = (currentPosition.X + 1); x <= 7; x++)
                {
                    Board.Square square = Board.GetSquare(x, rook2Y);
                    if (square.Occupied || square.GetThreatenedByList(this.Color).Count != 0)
                    {
                        castling = false;
                        break;
                    }
                }
            }
            if (castling)
            {
                Entities.SquareStatus squareStat = new SquareStatus(Board.GetSquare(rook2X, rook2Y), MoveResult.valid & MoveResult.castling);
                validPositions.Add(squareStat);
            }

            #endregion

            return validPositions;
        }

        #endregion
    }
}
